#pragma once
#include "safe_handle.hpp"
#include "wxx_error.hpp"

namespace wxx
{
	using namespace detail;
	using namespace safe_handles;

	struct process_info : safe_handle<nt_handle>
	{
		enum access_type
		{
			access_all              = PROCESS_ALL_ACCESS,
			access_create_process   = PROCESS_CREATE_PROCESS,
			access_create_thread    = PROCESS_CREATE_THREAD,
			access_duplicate_handle = PROCESS_DUP_HANDLE,
		};

		explicit process_info(handle_type handle)
			: safe_handle(handle)
		{
		}

		explicit process_info(unsigned int id, enum access_type access, bool inheritable = false)
			: safe_handle(open(id, access, inheritable))
		{
		}

		unsigned int id() const throw()
		{
			return ::GetProcessId(handle());
		}

		bool is_wow64() const throw(...)
		{
			BOOL iswow64;
			ensure_success_win32(
				::IsWow64Process(handle(), &iswow64)
			);

			return iswow64 == TRUE;
		}

		static unsigned int current_id() throw()
		{
			return ::GetCurrentProcessId();
		}

		static process_info current(bool inheritable = false) throw(...)
		{
			return process_info(open(
				::GetCurrentProcessId(),
				access_all,
				inheritable
			));

		}

	private:

		static HANDLE open(unsigned int id, 
			               enum access_type access, 
						   bool inheritable) throw(...)
		{
			return ensure_success_win32(
				::OpenProcess(access, inheritable, id)
			);
		}
	};
}